package config

import (
	"embed"
	"encoding/json"
	"fmt"
	"os"
	"strconv"
	"strings"
	"sync"
	"time"

	"gorm.io/driver/mysql"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

//go:embed config.json
var configFS embed.FS

type Config struct {
	IsDebug bool            `json:"is_debug"`
	Server  ServerConfig    `json:"server"`
	DB      DbConnectOption `json:"database"`
	Wework  Wework          `json:"wework"`
}

type ServerConfig struct {
	Port          int    `json:"port"`
	SecretKey     string `json:"secret_key"`
	OpenToken     string `json:"open_token"`
	AdminAliasMap string `json:"admin_alias_map"`
}

type DbConnectOption struct {
	Host        string        `json:"host"`
	Database    string        `json:"database"`
	Port        int           `json:"port"`
	User        string        `json:"user"`
	Pass        string        `json:"pass"`
	MaxOpenConn int           `json:"max_open"`
	MaxIdleConn int           `json:"max_idle"`
	MaxLifeTime time.Duration `json:"max_life_time"`
}

type Wework struct {
	CorpID         string `json:"corp_id"`          //企业ID（在企微后台“我的企业”中查看）
	CorpSecret     string `json:"corp_secret"`      //自建应用密钥
	AgentID        int    `json:"agent_id"`         //自建应用ID（在企微后台“应用管理”中查看）
	EncodingAesKey string `json:"encoding_aes_key"` //服务商配置的EncodingAesKey
	AgentDomain    string `json:"agent_domain"`     //代理域名
}

var GlobalConfig *Config
var once sync.Once

func Init() {
	// 设置全局时区为上海
	loc, err := time.LoadLocation("Asia/Shanghai")
	if err != nil {
		panic(err)
	}
	time.Local = loc // 关键！设置全局本地时区

	// 加载配置
	LoadConfig("config.json")
	// 初始化db
	InitDb()

}

// LoadConfig 支持环境变量覆盖的配置加载
func LoadConfig(path string) {
	once.Do(func() {
		// 从嵌入文件读取基础配置
		data, err := configFS.ReadFile(path)
		if err != nil {
			panic(fmt.Sprintf("读取配置文件失败: %v", err))
		}

		// JSON反序列化
		if err := json.Unmarshal(data, &GlobalConfig); err != nil {
			panic(fmt.Sprintf("解析配置文件失败: %v", err))
		}

		// 环境变量覆盖
		// is_debug
		{
			isDebug := strings.ToLower(os.Getenv("IS_DEBUG"))
			if isDebug != "" {
				GlobalConfig.IsDebug = isDebug == "true" || isDebug == "1" || isDebug == "yes" || isDebug == "on"
			}

		}

		// server
		{
			port := os.Getenv("PORT")
			if port != "" {
				GlobalConfig.Server.Port, _ = strconv.Atoi(port)
			}

			secretKey := os.Getenv("SECRET_KEY")
			if secretKey != "" {
				GlobalConfig.Server.SecretKey = secretKey
			}

			openToken := os.Getenv("OPEN_TOKEN")
			if openToken != "" {
				GlobalConfig.Server.OpenToken = openToken
			}

			adminAliasMap := os.Getenv("ADMIN_ALIAS_MAP")
			if adminAliasMap != "" {
				GlobalConfig.Server.AdminAliasMap = adminAliasMap
			}
		}

		// db
		{
			dbHost := os.Getenv("DB_HOST")
			if dbHost != "" {
				GlobalConfig.DB.Host = dbHost
			}

			dbDatabase := os.Getenv("DB_DATABASE")
			if dbDatabase != "" {
				GlobalConfig.DB.Database = dbDatabase
			}

			dbUser := os.Getenv("DB_USER")
			if dbUser != "" {
				GlobalConfig.DB.User = dbUser
			}

			dbPassword := os.Getenv("DB_PASSWORD")
			if dbPassword != "" {
				GlobalConfig.DB.Pass = dbPassword
			}

			dbPort := os.Getenv("DB_PORT")
			if dbPort != "" {
				GlobalConfig.DB.Pass = dbPort
			}

		}

		// wework
		{

			weworkCorpID := os.Getenv("WEWORK_CORP_ID")
			if weworkCorpID != "" {
				GlobalConfig.Wework.CorpID = weworkCorpID
			}

			weworkCorpSecret := os.Getenv("WEWORK_CORP_SECRET")
			if weworkCorpSecret != "" {
				GlobalConfig.Wework.CorpSecret = weworkCorpSecret
			}
			weworkAgentID := os.Getenv("WEWORK_AGENT_ID")
			if weworkAgentID != "" {
				GlobalConfig.Wework.AgentID, _ = strconv.Atoi(weworkAgentID)
			}

			weworkEncodingAesKey := os.Getenv("WEWORK_ENCODING_AES_KEY")
			if weworkEncodingAesKey != "" {
				GlobalConfig.Wework.EncodingAesKey = weworkEncodingAesKey
			}

			weworkAgentDomain := os.Getenv("WEWORK_AGENT_DOMAIN")
			if weworkAgentDomain != "" {
				GlobalConfig.Wework.AgentDomain = weworkAgentDomain
			}
		}
	})
}

var DB *gorm.DB

func InitDb() {
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8mb4&parseTime=True&loc=Local",
		GlobalConfig.DB.User, GlobalConfig.DB.Pass, GlobalConfig.DB.Host, GlobalConfig.DB.Port, GlobalConfig.DB.Database)

	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		CreateBatchSize: 1000,                                  // 全局默认批次大小
		Logger:          logger.Default.LogMode(logger.Silent), // 禁用日志
	})
	if err != nil {
		panic(fmt.Sprintf("无法连接数据库: %v", err))
	}

	if GlobalConfig.IsDebug {
		db = db.Debug()
	}
	DB = db
}
